package acm;

import testing.*;
import java.util.ArrayList;
import java.util.Iterator;


/**
 *
 */
public class BinarioPalindrome {

	private int intervaloMin; // intervalo minimo
	private int intervaloMax; // intervalo maximo
	private ArrayList<String> listaBinarios;
	private ArrayList<String> listaPalindromes;

	/**
	 * Constructor que recibe dos parametros, los inicializa e inicializa dos
	 * listas en las que se almacenaran los binarios y palindromes resultantes.
	 * 
	 * @param numero
	 *            minimo de un intervalo
	 * @param numero
	 *            maximo de un intervalo
	 */

	public BinarioPalindrome(int intervaloMin, int intervaloMax) {

		this.intervaloMin = intervaloMin; 
		this.intervaloMax = intervaloMax;
		this.listaBinarios = new ArrayList<String>();
		this.listaPalindromes = new ArrayList<String>();

	}

	/**
	 * Constructor vacio
	 */
	public BinarioPalindrome() {
		
	}

	/**
	 * Valida los numeros minimos y maximos de un intervalo.
	 * 
	 * @param numero
	 *            minimo de un intervalo
	 * @param numero
	 *            maximo de un intervalo
	 * @return true si ambos estan entre 1 y 2000. En caso contrario, retorna
	 *         falso.
	 */
	public Boolean validarIntervalo(Object int1, Object int2) {

		Boolean res = true;
		
		int base = 0;
		int extremo = 0;
		
		try{
			
			base = (int)int1;
			extremo = (int)int2;
			
		}catch(ClassCastException err){
			res = false;
		}

		if (base > extremo) {

			System.out.println("intervalos intercambiados");
			res = false;

		} else {

			if ((base>1 && base<2000) && (extremo>1 && extremo<2000)) {
				System.out.println("Correcto");
				res = true;
			} else {

				System.out.println("fuera de limites");
				res = false;
			}

		}
		return res;
		
	}
	
	/**
	 * Metodo que reune los metodos de la clase, calcula el palindrome de los binarios y los muestra.
	 * 
	 */
	public void calcularPalindrome() {
		this.transformarBinario();
		this.verificarPalindrome();
		this.mostrarListas();

	}
	

	/**
	 * Metodo que transforma todos los numeros que pertenecen 
	 * al intervalo ingresado, a binario.
	 * 
	 */
	public void transformarBinario() {

		if (this.validarIntervalo(this.intervaloMin, this.intervaloMax) == Boolean.TRUE) {

			for (int index = this.intervaloMin; index <= this.intervaloMax; index++) { 
																						

				this.listaBinarios.add(Integer.toBinaryString(index)); 
				//System.out.println("lista");

			}

		} else {

			System.out.println("Intervalos invalidos. Ingrese numeros entre 1 y 2000. (intervalo menor, intervalo mayor)\n");

		}

	}

	/**
	 * Metodo que verifica si los numeros del intervalo transformados a binarios,
	 * son palindromes.
	 * 
	 */
	public void verificarPalindrome() {


		Iterator<String> iterador = this.listaBinarios.iterator();

		while (iterador.hasNext()) {

			String numeroBinario = iterador.next();
			boolean palindrome = true;

			for (int index = 0; index < ((int) (numeroBinario.length() / 2)); index++) {

				if (numeroBinario.charAt(index) != numeroBinario
						.charAt(numeroBinario.length() - index - 1)) {

					palindrome = false; 
										
				}
			}

			if (palindrome) {

				this.listaPalindromes.add(numeroBinario);
			}
		}

	}

	/**
	 * Metodo que muestra los numeros binarios palindromes.
	 * @return cadena de binarios palindromes
	 */
	public String mostrarListas() {

		String salida = "";

		Iterator<String> iteradorBinario = this.listaBinarios.iterator();
		Iterator<String> iteradorPalindrome = this.listaPalindromes.iterator();

		salida += "Binarios\n";

		int numero = this.intervaloMin; // intervalo minimo

		while (iteradorBinario.hasNext()) {

			salida += "(" + numero + ") " + iteradorBinario.next() + "\n"; 																			
			numero++;
		}

		salida += "Palindrome\n";

		while (iteradorPalindrome.hasNext()) {

			salida += iteradorPalindrome.next() + "\n";
		}

		return salida;
	}



}
